#include "io.h"
#include "../commons/mapa.h"
#include "../commons/errors.h"

void freeMapa(mapa_t mapa)
{
	if(mapa){
		int i, j;
		for(i=0 ; i < mapa->ciudadesCant; i++){
			for(j=0 ; j < (mapa->ciudades[i])->drogasCant; j++){
				free(((mapa->ciudades[i])->drogas[j])->nombre);
				free((mapa->ciudades[i])->drogas[j]);
			}
			free((mapa->ciudades[i])->drogas);
			free((mapa->ciudades[i])->nombre);
			free(mapa->ciudades[i]);
		}
		for(i=0 ; i < mapa->ciudadesCant; i++)
		    free(mapa->distancias[i]);
		
		free(mapa->distancias);
		free(mapa->ciudades);
		free(mapa);
	}
}

int CargoDistancia(mapa_t mapa, char* ciudad1, char* ciudad2, int distancia)
{
        int x = getPos( mapa, ciudad1);
        int y = getPos( mapa, ciudad2);
        
        if( (x >= 0) && (x < mapa->ciudadesCant) && (y >= 0) && (y < mapa->ciudadesCant)){
            mapa->distancias[x][y]=distancia;
            mapa->distancias[y][x]=distancia;
            
            return NO_ERRORS;
            
        }else{
            return ERR_FILE;
        }
        
}

int getPos(mapa_t mapa, char * ciudad){
  
        int i;
        for( i = 0 ; i < mapa->ciudadesCant ; i++){       
              if(strcmp((mapa->ciudades[i])->nombre, ciudad)==0)
                    return i;         
        }
        return ERR_FILE;
  
}

int inicDistancias(mapa_t mapa){
  
        mapa->distancias = (int **)malloc(mapa->ciudadesCant*mapa->ciudadesCant*sizeof(int *));
        
        if(mapa->distancias == NULL) return MEMORY_ERROR;
        
        int i, j;
        for( i = 0 ; i < mapa->ciudadesCant ; i++){
            mapa->distancias[i] = (int *)malloc(mapa->ciudadesCant*sizeof(int *)); 
            if(mapa->distancias[i] == NULL) return MEMORY_ERROR;
        }
        
        for( i = 0 ; i < mapa->ciudadesCant ; i++)
            for( j = 0 ; j < mapa->ciudadesCant ; j++){
                  if(i==j){               
                    mapa->distancias[i][j]=0;               
                  }else{                    
                    mapa->distancias[i][j]=-1;              
                  }
            }
            
         return NO_ERRORS;
  
}




int allocDrogasCiudad(ciudad_t ciudad, int drogasCant)
{	
        if(drogasCant == 1){
                    ciudad->drogas = (droga_t *)malloc(drogasCant * sizeof(struct st_droga_t));
        }else{
            ciudad->drogas = (droga_t *)realloc(ciudad->drogas, drogasCant * sizeof(struct st_droga_t));
        }
        if(ciudad->drogas == NULL) return MEMORY_ERROR;

	return NO_ERRORS;
}



int allocCiudades(mapa_t mapa, int ciudadesCant)
{
        mapa->ciudades = (ciudad_t *)malloc(ciudadesCant * sizeof(struct st_ciudad_t));
        if(mapa->ciudades == NULL) return MEMORY_ERROR;
        
        return NO_ERRORS;
}


int loadMapa(mapa_t mapa, char * fileName)
{
        int ciudadesCant;
        char nombre[MAX_NAME];
        int drogaCant;
        char drogaName[MAX_NAME];
        
        FILE * file;

        file = fopen(fileName,"r");
        
        if(file == NULL) 
                return ERR_FILE;
        
        /*Cargo Cant de ciudades*/
        
        if((fscanf(file, "%d\n" ,&ciudadesCant) == 1) && (ciudadesCant > 0)/* && (ciudadesCant < MAX_CIUD)*/){
        
            mapa->ciudadesCant=ciudadesCant;
            if(allocCiudades(mapa, ciudadesCant) != NO_ERRORS) return MEMORY_ERROR;
            
        }else{
         
            return ERR_FILE;
            
        }
        
        if(inicDistancias(mapa) != NO_ERRORS) return MEMORY_ERROR;
        
        int i;

        /*Cargo las ciudades*/
        for( i = 0 ; i < ciudadesCant ; i++){
          
          ciudad_t ciudad = (ciudad_t) malloc(sizeof(struct st_ciudad_t));
          if(ciudad == NULL) return MEMORY_ERROR;
          
          if((fscanf(file, "%s\n" , (char *)&nombre ) != 1)){
            
            return ERR_FILE;
            
          }
          nombre[strlen(nombre)]='\0';
          ciudad->nombre = (char *) malloc(strlen(nombre)+1);
          if(ciudad->nombre == NULL) return MEMORY_ERROR;
          strcpy(ciudad->nombre, nombre);
          
          
         /*Cargo las drogas*/ 
         int cantDrogas=0;
         
         fpos_t posicion;
         fgetpos(file, &posicion);
          while(fscanf(file, "%s %d\n" , drogaName, &drogaCant) == 2){
              fgetpos(file, &posicion);
          
              droga_t droga = (droga_t) malloc(sizeof(struct st_droga_t));
              if(droga == NULL) return MEMORY_ERROR;
              
              droga->nombre = (char *) malloc(strlen(drogaName)+1);
              if(droga->nombre == NULL) return MEMORY_ERROR;
              
              strcpy(droga->nombre, drogaName);
              droga->cant=drogaCant;
              
              cantDrogas++;
              ciudad->drogasCant=cantDrogas;
              if(allocDrogasCiudad(ciudad, cantDrogas) != NO_ERRORS) return MEMORY_ERROR;
                      
              ciudad->drogas[cantDrogas-1]=droga;
            
          }
          
         fsetpos(file, &posicion);
         mapa->ciudades[i] = ciudad; 
                  
        }
        
        /*Cargo las distancias*/
        
        char ciudad1[MAX_NAME], ciudad2[MAX_NAME];
        int distancia;
        
        int ret;
        while((ret = fscanf(file, "%s %s %d\n" , ciudad1, ciudad2, &distancia)) == 3)
              if(CargoDistancia(mapa, ciudad1, ciudad2, distancia) == ERR_FILE) return ERR_FILE;
	      
	fclose(file);
              
        return NO_ERRORS;       
        
}




